package com.xiaoq.sites.endpoint;

import com.xiaoq.ESIndexNameProperties;
import com.xiaoq.baiduunit.entity.WeatherResult;
import com.xiaoq.baiduunit.service.UnitService;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.*;
import com.xiaoq.flowrate.service.IFlowrateService;
import com.xiaoq.sites.entity.SitesAnnouncementEntity;
import com.xiaoq.sites.entity.SitesEntity;
import com.xiaoq.sites.entity.SitesHotSearchEntity;
import com.xiaoq.sites.service.ISitesService;
import com.xiaoq.sites.vo.*;
import com.xiaoq.system.entity.ZoneMasterEntity;
import com.xiaoq.system.service.IZoneMasterService;
import com.xiaoq.vo.PagingVo;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Api(tags={"C端景区相关接口"})
@RestController
@RequestMapping("/api/v1")
public class SitesEndpoint2C {

	private static final class SiteDetailResponse extends GenericDataResponse<SitesDetailVo> {}
	private static final class SitesESDetailResponse extends GenericListResponse<SitesESDetailVo> {}
	private static final class SearchResultResponse extends GenericListResponse<SearchResultVo> {}
	private static final class SitesCountResponse extends GenericDataResponse<Long> {};
	private static final class SitesWeatherResponse extends GenericDataResponse<SitesWeatherVo> {}

	/**  景区流量  */
	private static final class TouristStaticsResponse extends GenericDataResponse<TouristStaticsVo> {}

	/**  景区搜索  */
	private static final class SitesSearchResponse extends GenericListResponse<SitesSearchVo> {}
	/**  活动搜索  */
	private static final class ActivitySearchResponse extends GenericListResponse<ActivitySearchVo> {}
	/**  头条搜索  */
	private static final class ContentSearchResponse extends GenericListResponse<ContentSearchVo> {}
	/**  门票搜索  */
	private static final class TicketSearchResponse extends GenericListResponse<TicketSearchVo> {}
	
	private static final class MiniMainUrlResponse extends GenericDataResponse<String> {}


	@Autowired
	private ElasticsearchTemplate template;
	
	private Logger logger = LoggerFactory.getLogger(SitesEndpoint2C.class);

	@Autowired
	private ESIndexNameProperties indexNameProperties;
	
	@Autowired
	private ISitesService sitesService;

	@Autowired
	private IFlowrateService flowrateService;
	@Autowired
	private IdGenerator idGenerator;
	@Autowired
	private IZoneMasterService zoneMasterService;
	@Autowired
	private UnitService unitService;

	@Autowired
	private ResourceLoader resourceLoader;

	@ApiOperation(value="获取小程序主图", notes="获取小程序主图")
	@ApiResponses({
			@ApiResponse(code = 200, response = MiniMainUrlResponse.class, message = "获取小程序主图")
	})
	@GetMapping(value="/sites/miniImgUrl", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> getMiniMainImgUrl(@RequestParam(value="sitesId")@ApiParam(value="sitesId")String sitesId) {
			SitesEntity sites = sitesService.findById(sitesId);
			String miniImgUrl = sites.getMiniImgUrl();
			if(miniImgUrl==null){
				miniImgUrl="http://p2ofwqfm5.bkt.clouddn.com/index.jpg";
			}
			return MiniMainUrlResponse.okWithData(miniImgUrl);
	}
	
	@ApiOperation(value="查询景区详情", notes="根据ID查询景区详情")
	@ApiResponses({
			@ApiResponse(code = 200, response = SiteDetailResponse.class, message = "景区详情")
	})
	@GetMapping(value="/sites/{id}/detail", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> detailInfo(@PathVariable("id") @ApiParam(value="景区ID", required=true) String id) {

		String errorMsg = "查询景区详情出错";

		try {
			SitesEntity sites = sitesService.findById(id);

			if(StringUtils.isBlank(id) || sites==null) {
				return GenericResponse.ng("景区不存在");
			}

			SitesDetailVo sitesDetailVo = new SitesDetailVo();
			Long capacity = sites.getCapacity();
			if(sites != null && StringUtils.isNotBlank(sites.getId())) {
				sitesDetailVo.setAddress(sites.getAddress());
				sitesDetailVo.setAvgTime(sites.getAvgTime());
				sitesDetailVo.setBestPeriod(sites.getBestPeriod());
				sitesDetailVo.setCenterLatitude(sites.getCenterLatitude());
				sitesDetailVo.setCenterLongitude(sites.getCenterLongitude());
				sitesDetailVo.setDetailInfo(sites.getDetailInfo());
				sitesDetailVo.setEnterCert(sites.getEnterCert());
				sitesDetailVo.setId(sites.getId());
				sitesDetailVo.setImgUrls(sites.getImgUrls());
				sitesDetailVo.setIntroduction(sites.getIntroduction());
				sitesDetailVo.setLevels(sites.getLevels()==null?0:sites.getLevels());
				sitesDetailVo.setMainEntryLatitude(sites.getMainEntryLatitude());
				sitesDetailVo.setMainEntryLongitude(sites.getMainEntryLongitude());
				sitesDetailVo.setMainImgUrl(sites.getMainImgUrl());
				sitesDetailVo.setMerchantId(sites.getMerchantId());
				sitesDetailVo.setName(sites.getName());
				sitesDetailVo.setNotice(sites.getNotice());
				sitesDetailVo.setOpenSchedule(sites.getOpenSchedule());
				sitesDetailVo.setPhoneNum(sites.getPhoneNum());
				sitesDetailVo.setPrefPolicy(sites.getPrefPolicy());
				sitesDetailVo.setShortName(sites.getShortName());
				sitesDetailVo.setTags(sites.getTags());
				sitesDetailVo.setTips(sites.getTips());
				sitesDetailVo.setTraficTips(sites.getTraficTips());
				sitesDetailVo.setZoneCity(sites.getZoneCity());
				sitesDetailVo.setZoneCityName(sites.getZoneCityName());
				sitesDetailVo.setZoneDistrictName(sites.getZoneDistrictName());
				sitesDetailVo.setZoneProvinceName(sites.getZoneProvinceName());

				ZoneMasterEntity zoneMasterEntity = zoneMasterService.getZoneMasterByCode(sites.getZoneCity());

				if(zoneMasterEntity!=null && zoneMasterEntity.getName()!=null){
					sitesDetailVo.setZoneCityName(zoneMasterEntity.getName());
				}else {
					sitesDetailVo.setZoneCityName("");
				}

				sitesDetailVo.setZoneDistrict(sites.getZoneDistrict());
				sitesDetailVo.setZoneProvince(sites.getZoneProvince());
				sitesDetailVo.setMaxRadius(sites.getMaxRadius());
				sitesDetailVo.setStatus(sites.getStatus());
				sitesDetailVo.setCapacity(capacity);
			}

			AnnouncementVo announcementVo = null;
			List<AnnouncementVo> announcementVoList = new ArrayList<>();
			List<SitesAnnouncementEntity> sitesAnnouncementList = sitesService.findSitesAnnouncementListBySitesId(id);
			if(CollectionUtils.isNotEmpty(sitesAnnouncementList)) {
				for (SitesAnnouncementEntity sitesAnnouncement : sitesAnnouncementList) {
					announcementVo = new AnnouncementVo();
					announcementVo.setContent(sitesAnnouncement.getContent());
					announcementVo.setId(sitesAnnouncement.getId());
					announcementVo.setPubTime(sitesAnnouncement.getPubTime());
					announcementVo.setTitle(sitesAnnouncement.getTitle());
					announcementVo.setWarnLevel(sitesAnnouncement.getWarnLevel());

					announcementVoList.add(announcementVo);
				}
				sitesDetailVo.setAnnouncements(announcementVoList);
			}

			//设置客流量 TouristStaticsVo,因为要调用景区HTTP的接口，影响访问速度，故单独写个接口访问流量
			TouristStaticsVo touristStaticsVo = new TouristStaticsVo();
			touristStaticsVo.setCongestionIdx(-1);
			touristStaticsVo.setCount(-1L);
			sitesDetailVo.setTouristStatics(touristStaticsVo);
			return SiteDetailResponse.okWithData(sitesDetailVo);
		} catch (Exception e) {
			logger.error(errorMsg,e);
			return GenericResponse.ng(errorMsg);
		}
	}

	//TouristStaticsResponse
	@ApiOperation(value="获取景区流量", notes="获取景区流量")
	@ApiResponses({
			@ApiResponse(code = 200, response = TouristStaticsResponse.class, message = "获取景区流量")
	})
	@GetMapping(value="/sites/{id}/touristStatics", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> touristStatics(@PathVariable("id") @ApiParam(value="景区ID", required=true) String id) {
		try {
			SitesEntity sites = sitesService.findById(id);

			if(StringUtils.isBlank(id) || sites==null) {
				TouristStaticsVo touristStaticsVo = new TouristStaticsVo();
				touristStaticsVo.setCongestionIdx(-1);
				touristStaticsVo.setCount(-1L);
				return TouristStaticsResponse.okWithData(touristStaticsVo);
			}

			Long capacity = sites.getCapacity();
			if(capacity == null){
				capacity = 50L;
			}

			//设置客流量 TouristStaticsVo
			TouristStaticsVo touristStaticsVo = flowrateService.findTouristStatics(id,capacity);
			return TouristStaticsResponse.okWithData(touristStaticsVo);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			return GenericResponse.ng("获取景区流量失败");
		}
	}
	
	@ApiOperation(value="根据城市当前位置查询景区列表", notes="根据城市当前位置查询景区列表")
	@ApiResponses({
		@ApiResponse(code = 200, response = SitesESDetailResponse.class, message = "根据城市当前位置查询景区列表")
	})
	@GetMapping(value="/sites", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> sitesListByLBS(@RequestParam(name="k", required=false) @ApiParam(value="搜索词", required=false) String k,
			@RequestParam(name="userId", required=false) @ApiParam(value="用户Id", required=false) String userId,
			@RequestParam(name="city", required=false) @ApiParam(value="城市code", required=false) String city,
			@RequestParam(name="district", required=false) @ApiParam(value="区县编码", required=false) String district,
			@RequestParam(name="lng", required=false) @ApiParam(value="经度", required=false) Double lng,
			@RequestParam(name="lat", required=false) @ApiParam(value="纬度", required=false) Double lat,
			HttpServletRequest request) {

		int page = 0, size = 100;
		if(StringUtils.isBlank(city) || !StringUtils.isNumeric(city)) {
			return GenericResponse.ng("城市code错误");
		}

		List<SitesESDetailVo> sitesESDetailVoList = new ArrayList<>();
		List<SitesEntity> sitesEntityList;
		if(k!=null && StringUtils.isNotBlank(k.trim())) {
			sitesEntityList = sitesService.findSitesFromESByCityCodeAndKeyWord(city, k, page, size);
		}else {
			//处理 k 为 null,直接从redis/mongo里取
			sitesEntityList = sitesService.findSitesListbyZoneCity(city,district);
		}

		if(CollectionUtils.isEmpty(sitesEntityList)){
			//直接取贵阳的数据
			sitesEntityList = sitesService.findSitesListbyZoneCity("520100",null);
		}

		if(CollectionUtils.isNotEmpty(sitesEntityList)) {
			SitesESDetailVo sitesESDetailVo;
			for (SitesEntity sitesEntity : sitesEntityList) {
				sitesESDetailVo = new SitesESDetailVo();
				sitesESDetailVo.setCenterLatitude(sitesEntity.getCenterLatitude());
				sitesESDetailVo.setCenterLongitude(sitesEntity.getCenterLongitude());
				sitesESDetailVo.setDistance(MathUtil.distance(lng,lat,sitesEntity.getMainEntryLongitude(),sitesEntity.getMainEntryLatitude()));  //根据经纬度计算距离  TODO
				sitesESDetailVo.setId(sitesEntity.getId());
				sitesESDetailVo.setImgUrl(sitesEntity.getMainImgUrl());
				sitesESDetailVo.setIntroduction(sitesEntity.getIntroduction());
				sitesESDetailVo.setLevels(sitesEntity.getLevels());
				sitesESDetailVo.setMainEntryLatitude(sitesEntity.getMainEntryLatitude());
				sitesESDetailVo.setMainEntryLongitude(sitesEntity.getMainEntryLongitude());
				sitesESDetailVo.setName(sitesEntity.getName());
				sitesESDetailVo.setShortName(sitesEntity.getShortName());
				sitesESDetailVo.setTags(sitesEntity.getTags());
				sitesESDetailVo.setMaxRadius(sitesEntity.getMaxRadius());
				sitesESDetailVo.setStatus(sitesEntity.getStatus());
				sitesESDetailVo.setType(10);  // 暂时只搜景区    TODO
				sitesESDetailVo.setZoneCode(sitesEntity.getZoneCity());  // 暂时只搜城市景区    TODO
				sitesESDetailVo.setDistanceString(MathUtil.distance(sitesESDetailVo.getDistance()));

				sitesESDetailVoList.add(sitesESDetailVo);
			}

			//升序排序
			sitesESDetailVoList.sort((sites1,sites2) -> sites1.getDistance().compareTo(sites2.getDistance()));
//				SitesESDetailVo tmpSitesDetailVo = sitesESDetailVoList.remove(0);
//				sort(tmpSitesDetailVo.getMainEntryLatitude(),tmpSitesDetailVo.getMainEntryLongitude(),sitesESDetailVoList);
//				sitesESDetailVoList.add(0, tmpSitesDetailVo);
		}

		return SitesESDetailResponse.listNoCount(sitesESDetailVoList);

	}

	/**
	 *  计算 sitesESDetailVoList 距离(lng, lat)的距离，按升序排序
	 * @param lat 纬度
	 * @param lng 经度
	 * @param sitesESDetailVoList
	 * @return sitesESDetailVoList
	 */
	private List<SitesESDetailVo> sort(Double lat, Double lng, List<SitesESDetailVo> sitesESDetailVoList){
		if(CollectionUtils.isNotEmpty(sitesESDetailVoList)){
			for(SitesESDetailVo sitesESDetailVo: sitesESDetailVoList){
				sitesESDetailVo.setDistance(MathUtil.distance(lng,lat,
						sitesESDetailVo.getMainEntryLongitude(),sitesESDetailVo.getMainEntryLatitude()));
			}
			//升序排序
			sitesESDetailVoList.sort((sites1,sites2) -> sites1.getDistance().compareTo(sites2.getDistance()));
		}
		return sitesESDetailVoList;
	}
	
	@ApiOperation(value="景区/门票/目的地/活动/内容", notes="景区/门票/目的地/活动/内容")
	@ApiResponses({
		@ApiResponse(code = 200, response = SearchResultResponse.class, message = "景区/门票/目的地/活动/内容")
	})
	@GetMapping(value="/search/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k) {

		if(k==null || StringUtils.isBlank(k.trim())) {
			return GenericResponse.ng("搜索关键字不能为空");
		}
		List<SearchResultVo> resultVoList = new ArrayList<>();

		ExecutorService executorService = new ThreadPoolExecutor(4, 4,
				0L, TimeUnit.SECONDS,
				new ArrayBlockingQueue<>(5));
		//分页
		PagingVo pagingVo = new PagingVo(0, 5);

		List<Future<List<SearchResultVo>>> futureList = new ArrayList<>(5);
		futureList.add(executorService.submit(()->sitesService.findZoneMasterFromEsByName(k, pagingVo)));
		futureList.add(executorService.submit(()->sitesService.findSitesFromEsByTitle(k, pagingVo)));
		futureList.add(executorService.submit(()->sitesService.findActivityFromEsByTitle(k, pagingVo)));
		futureList.add(executorService.submit(()->sitesService.findContentFromEsByTitle(k, pagingVo)));
		futureList.add(executorService.submit(()->sitesService.findTicketFromEsByName(k, pagingVo)));

		for(Future<List<SearchResultVo>> future : futureList){
			try {
				resultVoList.addAll(future.get(2, TimeUnit.SECONDS));
			}catch (Exception e){
				logger.error(e.getMessage(), e);
			}
		}

		executorService.shutdown();
		resultVoList.sort((item1,item2)-> {
			if(item1.getType() != null){
				return item1.getType().compareTo(item2.getType());
			}else if(item2.getType() != null){
				return item2.getType().compareTo(item1.getType());
			}else {
				return 0;
			}
		});

		return SearchResultResponse.listNoCount(resultVoList);
	}

	@ApiOperation(value="搜索目的地", notes="搜索目的地")
	@ApiResponses({
			@ApiResponse(code = 200, response = SearchResultResponse.class, message = "搜索目的地")
	})
	@GetMapping(value="/search4dest/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search4Dest(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k,
										 @ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
										 @ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

		if(k==null || StringUtils.isBlank(k = k.trim())) {
			return GenericResponse.ng("搜索关键字不能为空");
		}
		PagingVo pagingVo = new PagingVo(pn-1, ps);
		List<SearchResultVo> resultVoList = sitesService.findZoneMasterFromEsByName(k,pagingVo);

		return SearchResultResponse.listAndCount(resultVoList, resultVoList.size());
	}

	@ApiOperation(value="搜索景区", notes="搜索景区")
	@ApiResponses({
			@ApiResponse(code = 200, response = SitesSearchResponse.class, message = "搜索景区")
	})
	@GetMapping(value="/search4sites/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search4Sites(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k,
										  @ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
										  @ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

		if(k==null || StringUtils.isBlank(k = k.trim())) {
			return SearchResultResponse.listNoCount(new ArrayList<>());
		}
		PagingVo pagingVo = new PagingVo(pn-1, ps);
		List<SitesSearchVo> sitesSearchList = sitesService.findSitesSearchFromEsByTitle(k, pagingVo);

		return SitesSearchResponse.listAndCount(sitesSearchList, sitesSearchList.size());
	}

	@ApiOperation(value="搜索活动", notes="搜索活动")
	@ApiResponses({
			@ApiResponse(code = 200, response = ActivitySearchResponse.class, message = "搜索活动")
	})
	@GetMapping(value="/search4activity/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search4Activity(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k,
											 @ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
											 @ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

		if(k==null || StringUtils.isBlank(k = k.trim())) {
			return SearchResultResponse.listNoCount(new ArrayList<>());
		}
		PagingVo pagingVo = new PagingVo(pn-1, ps);
		List<ActivitySearchVo> activitySearchList = sitesService.findActivitySearchFromEsByTitle(k, pagingVo);

		return ActivitySearchResponse.listAndCount(activitySearchList, activitySearchList.size());
	}

	@ApiOperation(value="搜索(头条)内容", notes="搜索(头条)内容")
	@ApiResponses({
			@ApiResponse(code = 200, response = ContentSearchResponse.class, message = "搜索(头条)内容")
	})
	@GetMapping(value="/search4content/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search4Content(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k,
											@ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
											@ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

		if(k==null || StringUtils.isBlank(k = k.trim())) {
			return ContentSearchResponse.listNoCount(new ArrayList<>());
		}
		PagingVo pagingVo = new PagingVo(pn-1, ps);
		List<ContentSearchVo> contentSearchList = sitesService.findContentSearchFromEsByTitle(k, pagingVo);
		return ContentSearchResponse.listAndCount(contentSearchList, contentSearchList.size());
	}

	@ApiOperation(value="热搜词列表", notes="热搜词列表")
	@ApiResponses({
		@ApiResponse(code = 200, response = SearchResultResponse.class, message = "返回热搜索词列表")
	})
	@GetMapping(value="/hotsearch", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> listSitesHotSearch() {

		List<SearchResultVo> resultVoList = new ArrayList<>();
		List<SitesHotSearchEntity> sitesHotSearchEntityList = sitesService.getSitesHotSearchList();
		if(CollectionUtils.isEmpty(sitesHotSearchEntityList)){
			return SearchResultResponse.listNoCount(resultVoList);
		}

		SearchResultVo searchResultVo;
		for(SitesHotSearchEntity sitesHotSearch : sitesHotSearchEntityList){
			searchResultVo = new SearchResultVo();
			searchResultVo.setZoneCity(sitesHotSearch.getZoneCity());
			searchResultVo.setSourceTitle(sitesHotSearch.getMatchTxt());
			searchResultVo.setType(sitesHotSearch.getSearchType());
			searchResultVo.setContent(sitesHotSearch.getMatchTxt());
			searchResultVo.setShopId(sitesHotSearch.getShopId());
			//TODO 景区的id 和shopId 是一样的
			searchResultVo.setId(sitesHotSearch.getShopId());
			resultVoList.add(searchResultVo);
		}
		return SearchResultResponse.listNoCount(resultVoList);
	}

	@ApiOperation(value="搜索门票", notes="搜索门票")
	@ApiResponses({
			@ApiResponse(code = 200, response = TicketSearchResponse.class, message = "搜索门票")
	})
	@GetMapping(value="/search4ticket/{k}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> search4ticket(@PathVariable("k") @ApiParam(value="搜索关键字", required=true) String k,
											@ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
										    @ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

		if(k==null || StringUtils.isBlank(k = k.trim())) {
			return TicketSearchResponse.listNoCount(new ArrayList<>());
		}
		PagingVo page = new PagingVo(pn-1, ps);
		List<TicketSearchVo> ticketSearchList = sitesService.findTicketSearchFromEsByName(k, page);

		return TicketSearchResponse.listAndCount(ticketSearchList, ticketSearchList.size());
	}

	@ApiOperation(value = "添加热搜词", notes = "添加热搜词")
	@ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "添加热搜词") })
	@PostMapping(value = "/hotsearch", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> addHotsearch(HttpServletRequest request,
										  @RequestBody SearchResultVo searchResult) {
		String userId = (String) request.getAttribute("userId");

		try {
			SitesHotSearchEntity sitesHotSearch = new SitesHotSearchEntity();
			sitesHotSearch.setId(idGenerator.nextId());
			sitesHotSearch.setIp(NetUtil.getIpAddr(request));
			sitesHotSearch.setSearchTxt(searchResult.getSourceTitle());
			sitesHotSearch.setMatchTxt(searchResult.getSourceTitle());
			sitesHotSearch.setType(0); //
			sitesHotSearch.setUserId(userId);  //移动端传入，若没有userId.传iOS 或者 Android
			sitesHotSearch.setZoneCity(searchResult.getZoneCity());
			sitesHotSearch.setSearchType(searchResult.getType());
			sitesHotSearch.setShopId(searchResult.getShopId());
			sitesService.addSitesHotSearch(sitesHotSearch);
		}catch (Exception e){
			logger.error(e.getMessage(), e);
			return GenericResponse.ng("添加搜索词失败");
		}

		return GenericResponse.ok();
	}

	//切换城市时，判断该城市是否有景区上线
	@ApiOperation(value="切换城市时，判断该城市是否有景区上线0:未开通.>0已开通", notes="切换城市时，判断该城市是否有景区上线0:未开通.>0已开通")
	@ApiResponses({
			@ApiResponse(code = 200, response = SitesCountResponse.class, message = "切换城市时，判断该城市是否有景区上线,0:未开通.>0已开通")
	})
	@GetMapping(value="/cities/{zoneCity}/status", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> getCityStatus(
			@PathVariable("zoneCity") @ApiParam(value="城市编码", required=false) String zoneCity) {

		long sitesOnLineCount = sitesService.count(zoneCity, null,ConstantUtil.SITES_STATUS_ONLINE);
		return SitesCountResponse.okWithData(sitesOnLineCount);
	}
	
	@ApiOperation(value="(新的版本)切换城市时，判断该城市是否有景区上线0:未开通.>0已开通", notes="切换城市时，判断该城市是否有景区上线0:未开通.>0已开通")
	@ApiResponses({
			@ApiResponse(code = 200, response = SitesCountResponse.class, message = "切换城市时，判断该城市是否有景区上线,0:未开通.>0已开通")
	})
	@GetMapping(value="/cities/status", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> getCityStatus2(
			@RequestParam(value="zoneCity", required=false)@ApiParam(value="城市编码", required=false) String zoneCity,
			@RequestParam(value="zoneDistrict", required=false) @ApiParam(value="区县编码", required=false) String zoneDistrict) {

		long sitesOnLineCount = sitesService.count(zoneCity, zoneDistrict,ConstantUtil.SITES_STATUS_ONLINE);
		return SitesCountResponse.okWithData(sitesOnLineCount);
	}

	@ApiOperation(value="根据城市code获取城市天气", notes="根据城市code获取城市天气")
	@ApiResponses({
			@ApiResponse(code = 200, response = SitesWeatherResponse.class, message = "根据城市code获取城市天气")
	})
	@GetMapping(value="/cities/{zoneCity}/weather", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> getWeather(@PathVariable("zoneCity") @ApiParam(value="城市编码", required=true) String zoneCity) {

		SitesWeatherVo sitesWeatherVo = new SitesWeatherVo();
		ZoneMasterEntity zoneMasterEntity = zoneMasterService.getZoneMasterByCode(zoneCity);

		if(zoneMasterEntity == null){
			return SitesWeatherResponse.okWithData(sitesWeatherVo);
		}

		try {
			String response = unitService.getWeatherResponseString(zoneMasterEntity.getName());
			WeatherResult weatherResult = JsonUtil.asObject(response,WeatherResult.class);

			if(weatherResult != null){
				if(weatherResult.getTodayWeatehr() != null){
					BeanUtils.copyProperties(weatherResult.getTodayWeatehr(), sitesWeatherVo);
				}

				if(CollectionUtils.isNotEmpty(weatherResult.getResults())){
					sitesWeatherVo.setPm25(weatherResult.getResults().get(0).getPm25());
					sitesWeatherVo.setCurrentCity(weatherResult.getResults().get(0).getCurrentCity());
				}

				//替换新的图标
				String dayImgName = FilenameUtils.getName(sitesWeatherVo.getDayPictureUrl());
				Resource dayImgResource = resourceLoader.getResource("classpath:\\static\\images\\" + dayImgName);
				if(dayImgResource.exists()){
					String dayPicture = "https://sites.xiaoq.online/images/" + dayImgName;
					sitesWeatherVo.setDayPictureUrl(dayPicture);
				}
				String nightImgName = FilenameUtils.getName(sitesWeatherVo.getNightPictureUrl());
				Resource nightImgResource = resourceLoader.getResource("classpath:\\static\\images\\" + nightImgName);
				if(nightImgResource.exists()){
					String nightPicture = "https://sites.xiaoq.online/images/" + nightImgName;
					sitesWeatherVo.setNightPictureUrl(nightPicture);
				}
			}
		}catch (Exception e){
			logger.error(e.getMessage(), e);
			logger.error("获取天气失败! ");
		}

		return SitesWeatherResponse.okWithData(sitesWeatherVo);
	}

	@ApiOperation(value="根据城市名称获取天气", notes="根据城市名称获取天气")
	@ApiResponses({
			@ApiResponse(code = 200, response = SitesWeatherResponse.class, message = "根据城市名称获取天气")
	})
	@GetMapping(value="/cities/weather/{zoneName}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<?> getWeatherByZoneName(@PathVariable("zoneName") @ApiParam(value="城市名称", required=true) String zoneName) {

		SitesWeatherVo sitesWeatherVo = new SitesWeatherVo();

		if(StringUtils.isBlank(zoneName)){
			return SitesWeatherResponse.okWithData(sitesWeatherVo);
		}

		try {
			String response = unitService.getWeatherResponseString(zoneName);
			WeatherResult weatherResult = JsonUtil.asObject(response,WeatherResult.class);

			if(weatherResult != null){
				if(weatherResult.getTodayWeatehr() != null){
					BeanUtils.copyProperties(weatherResult.getTodayWeatehr(), sitesWeatherVo);
				}

				if(CollectionUtils.isNotEmpty(weatherResult.getResults())){
					sitesWeatherVo.setPm25(weatherResult.getResults().get(0).getPm25());
					sitesWeatherVo.setCurrentCity(weatherResult.getResults().get(0).getCurrentCity());
				}

				//替换新的图标
				String dayImgName = FilenameUtils.getName(sitesWeatherVo.getDayPictureUrl());
				Resource dayImgResource = resourceLoader.getResource("classpath:\\static\\images\\" + dayImgName);
				if(dayImgResource.exists()){
					String dayPicture = "https://sites.xiaoq.online/images/" + dayImgName;
					sitesWeatherVo.setDayPictureUrl(dayPicture);
				}
				String nightImgName = FilenameUtils.getName(sitesWeatherVo.getNightPictureUrl());
				Resource nightImgResource = resourceLoader.getResource("classpath:\\static\\images\\" + nightImgName);
				if(nightImgResource.exists()){
					String nightPicture = "https://sites.xiaoq.online/images/" + nightImgName;
					sitesWeatherVo.setNightPictureUrl(nightPicture);
				}
			}


		}catch (Exception e){
			logger.error(e.getMessage(), e);
			logger.error("获取天气失败! ");
		}

		return SitesWeatherResponse.okWithData(sitesWeatherVo);
	}
}